package cn.bx.bid.ctrl;


import cn.bx.bid.entity.*;
import cn.bx.bid.service.DepartmentService;
import cn.bx.bid.service.ProjectService;
import com.alibaba.fastjson.JSON;
import org.apache.http.HttpEntity;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

@Controller
//@RequestMapping("/user")
//控制器
public class ProjectController {
    //添加日志
    private static final Logger Log = LoggerFactory.getLogger(ProjectController.class);

    @Autowired
    //自动装载
    private ProjectService projectService;
    @Autowired
    private DepartmentService departmentService;

    @RequestMapping(value = "inputSettle", produces = "application/json;charset=UTF-8")
    @ResponseBody
    public boolean inputSettle(@RequestParam("projid") long projid, @RequestParam("dealCompany") String dealCompany, @RequestParam("settlePrice") double settlePrice) {
        int r = this.projectService.settleProject(projid, dealCompany, settlePrice);
        return r > 0;

    }

    //考虑把key放入外部文件中，好灵活配置
    public static final String url = "http://api.map.baidu.com/geocoder/v2/?address=%s&output=json&ak=B4bd9e22c0a580cd04b0e84b17bf9eb6";

    // 获得经纬度
    private Jw getPos(String addr) throws UnsupportedEncodingException {
        String str = getDistance(String.format(url, URLEncoder.encode(addr,"utf-8")));
        Map m = (Map) JSON.parse(str);

        if (!new Integer(0).equals(m.get("status"))) {
            return null;
        }
        Map m2 = (Map) ((Map) m.get("result")).get("location");
        System.out.println(m2);
        double lng = Double.parseDouble(m2.get("lng").toString());
        double lat = Double.parseDouble(m2.get("lat").toString());
        return new Jw(lat, lng);
    }

    //
    public String getDistance(String url) {
        // 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        // 创建Get请求
        HttpGet httpGet = new HttpGet(url);

        // 响应模型
        CloseableHttpResponse response = null;
        try {
            // 由客户端执行(发送)Get请求
            response = httpClient.execute(httpGet);
            // 从响应模型中获取响应实体
            HttpEntity responseEntity = response.getEntity();
            System.out.println("响应状态为:" + response.getStatusLine());
            if (responseEntity != null) {
                System.out.println("响应内容长度为:" + responseEntity.getContentLength());
                // System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
                return EntityUtils.toString(responseEntity);
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                // 释放资源
                if (httpClient != null) {
                    httpClient.close();
                }
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
//professorSearch2
    //开始抽选
    @RequestMapping(value = "randomSelect", produces = "application/json;charset=UTF-8")
    @ResponseBody
    public Object randomSelect(@RequestParam("pjid") long pjid, @RequestParam("category") String category, @RequestParam("distance") Double distance) {
        Project p = this.projectService.get(pjid);
        //考虑了能来的，去掉确定不来的，不确定的也加上了
        int hasSelected = this.projectService.getPrentProfessors(pjid);
        String msg = "";
        try {
            if (p.getStatus() == 1) {
                msg = "{\"result\":false,\"msg\":\"此项目已经结束，不能再选\"}";
            } else if (hasSelected >= p.getProfessorNum()) {
                msg = "{\"result\":false,\"msg\":\"此项目人数已经满足，无需再选\"}";
            } else {
                List<Professor> list = projectService.getProfessorsForChoose(pjid, category);
                //
                if (distance != null) {//distance>0
                    //根据距离过滤
                    Jw location = getPos(p.getAddress());//项目开标地址的经纬度
                    System.out.println("开会地点。。。。。。" + location);
                    if (location != null) {
                        Iterator<Professor> r = list.iterator();
                        while (r.hasNext()) {
                            Professor t = r.next();
                            Jw l2 = getPos(t.getAddress());//获得专家的经纬度
                            if (l2 == null)
                                continue;//地址不确定的先不考虑
                            System.out.println("专家：" + t.getProfessorName() + " 住址：" + l2 + ">>>距离：" + l2.dis(location) + "公里");
                            if (l2.dis(location) > distance) {
                                r.remove();//删除当前专家
                            }
                        }
                    }
                }
                if (list.size() < (p.getProfessorNum() - hasSelected)) {
                    msg = "{\"result\":false,\"msg\":\"没有找到满足人数的专家，缺少" + (Math.abs(list.size() - (p.getProfessorNum() - hasSelected))) + "人，先修改条件或者重新选择距离再试\"}";
                } else {
                    //开始随机选择
                    int need = p.getProfessorNum() - hasSelected;
                    long ids[] = new long[need];
                    int index = 0;
                    while (true) {
                        int r = (int) (Math.random() * list.size());
                        ids[index++] = list.get(r).getId();
                        list.remove(r);
                        if (index >= ids.length)
                            break;
                    }
                    //保存到数据库
                    int result = this.projectService.saveChooseResult(p, ids);
                    msg = "{\"result\":true,\"msg\":\"成功抽选" + need + "名专家！\"}";
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            msg = "{\"result\":false,\"msg\":\"网络不稳定，稍后再试！\"}";
        }
        return msg;
    }

    @RequestMapping(value = "projectChoosingProfs", produces = "application/json;charset=UTF-8")
    @ResponseBody
    public Page<ProfessorEnroll> projectChoosingProfs(@RequestParam("projid") long projid) {
        Page<ProfessorEnroll> p = this.projectService.searchProfessorInProjs(projid);
        return p;
    }
    @RequestMapping(value = "projectChoosingProfs2", produces = "application/json;charset=UTF-8")
    @ResponseBody
    public Object projectChoosingProfs2(@RequestParam("id") long id) {
        List<Professor> professors = this.projectService.searchProfessorInProjs2(id);
        return professors;
    }

    //确定参加
    @RequestMapping(value = "profRoleProject", produces = "application/json;charset=UTF-8")
    @ResponseBody
    public boolean profRoleProject(@RequestParam("pfid") long pfid, @RequestParam("projid") long projid) {
        int r = this.projectService.profRoleProject(pfid, projid);
        return r > 0;

    }

    //不参加
    @RequestMapping(value = "profnotPresentProject", produces = "application/json;charset=UTF-8")
    @ResponseBody
    public boolean profnotPresentProject(@RequestParam("pfid") long pfid, @RequestParam("proid") long proid, @RequestParam("reason") String reason) {
        int r = this.projectService.profnotPresentProject(pfid, proid, reason);
        return r > 0;

    }

    @RequestMapping(value = "projectGet", produces = "application/json;charset=UTF-8")
    @ResponseBody
    public Project projectGet(@RequestParam("id") long id) {
        Project project = this.projectService.get(id);
        return project;
    }

    @RequestMapping(value = "projectUpdate", produces = "application/json;charset=UTF-8")
    @ResponseBody
    //ModelAttribute  对象用这个注解
    public int projectUpdate(@ModelAttribute("user") Project user) {
        int isUpdate = this.projectService.update(user);
        return isUpdate;
    }

    @RequestMapping("projectSearch")
    @ResponseBody
    public Object paging(@RequestParam(value = "page", defaultValue = "1") int pageNo, @RequestParam(value = "limit", defaultValue = "10") int limit, @RequestParam(value = "projectName", required = false) String projectName, @RequestParam(value = "projectCategory", required = false) String projectCategory) {
        Page<Project> page = this.projectService.paging(pageNo, limit, projectName, projectCategory);
        return page;
    }

    //u还在上下文中，叫u
    @RequestMapping("projectAdd")
    @ResponseBody
    public int projectAdd(@ModelAttribute("u") Project u, HttpSession session) {
        User p = (User) session.getAttribute("User_Login");
        // System.out.println(p);
        u.setCreateBy(p.getName());
        u.setUpdateBy(p.getName());
        u.setCreateDate(new Date());
        u.setIsEvaluated("待抽签");
        u.setDepartment(this.departmentService.find(u.getDepartmentId()).getDepartmentName());
        int r = this.projectService.add(u);
        System.out.println(r);
        return r;
    }

    @RequestMapping("batchDelProject")
    @ResponseBody
    public Object batchDelProject(@RequestParam("ids[]") long[] ids) {
        int i = this.projectService.batchDel(ids);
        System.out.println(i);
        return i;
    }

    @InitBinder
    public void init(WebDataBinder binder) {
        CustomDateEditor dateEditor = new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true);
        binder.registerCustomEditor(Date.class, dateEditor);
    }
}

//经纬度描述类
class Jw {
    public double lat, lng;

    public Jw() {
    }

    public Jw(double lat, double lng) {
        super();
        this.lat = lat;
        this.lng = lng;
    }

    public double dis(Jw w) {
        return getDistance(this.lat, this.lng, w.lat, w.lng);
    }

    @Override
    public String toString() {
        return "Jw [lat=" + lat + ", lng=" + lng + "]";
    }

    public static double getDistance(double Lat_A, double Lng_A, double Lat_B, double Lng_B) {
        double ra = 6378.140;
        double rb = 6356.755;
        double flatten = (ra - rb) / ra;
        double rad_lat_A = Math.toRadians(Lat_A);
        double rad_lng_A = Math.toRadians(Lng_A);
        double rad_lat_B = Math.toRadians(Lat_B);
        double rad_lng_B = Math.toRadians(Lng_B);
        double pA = Math.atan(rb / ra * Math.tan(rad_lat_A));
        double pB = Math.atan(rb / ra * Math.tan(rad_lat_B));
        double xx = Math.acos(Math.sin(pA) * Math.sin(pB) + Math.cos(pA) * Math.cos(pB) * Math.cos(rad_lng_A - rad_lng_B));
        double c1 = (Math.sin((xx) - xx) * (Math.sin(pA) + Math.sin(pB)) * 2 / Math.cos(xx / 2) * 2);
        double c2 = (Math.sin(xx) + xx) * (Math.sin(pA) - Math.sin(pB)) * 2 / Math.sin(xx / 2) * 2;
        double dr = flatten / 8 * (c1 - c2);
        double distance = ra * (xx + dr);
        // DecimalFormat format = new DecimalFormat("###.000");
        // distance = Double.parseDouble(format.format(distance));
        return Math.abs(distance);
    }
}